/*****************************************************
This program was produced by the
CodeWizardAVR V1.25.8a Pro

Project : Termometr
Version : 3.0.0 ( +  ) 
Date    : 02.02.2008 ( )
Author  : Danil                          
Company : home                            
Comments:        ds18b20.lib
               int    float

Chip type           : ATtiny2313
Clock frequency     : 4,000000 MHz
Memory model        : Tiny
External SRAM size  : 0
Data Stack size     : 32
*****************************************************/
//
//    DS1307 - (PORTA bit 0 - SCL, bit 1 - SDA) 
//
//   DS18B20 - (PORTD bit 2)
//
//   -  (PORTD bit 0, 1)
//
//    (..)
//                    - (PORTB)   "-3 "
//                    - (PORTD) digit1 - bit 3, digit2 - bit 4, digit3 - bit 5, digit4 - bit 6                  
//

//  -          ,    IBM PC XT   Intel 8088 
#include <tiny2313.h>

// 1 Wire Bus functions (PORTD bit 2)
#asm
   .equ __w1_port=0x12
   .equ __w1_bit=2
#endasm

// I2C Bus functions (PORTA bit 0, 1)
#asm
   .equ __i2c_port=0x1b
   .equ __sda_bit=1
   .equ __scl_bit=0
#endasm

// DS18b20 Temperature Sensor functions
#include <ds18b20.h>  

// DS1307 I2C Bus Real Time Clock functions
#include <ds1307.h>

#include <delay.h> 
#include <bcd.h>

// flash unsigned char digits[], flash unsigned char cursor[]
//  
#include "term.h"        
  
unsigned char digit_out[4], cur_dig;
bit zpt_ON;
int temperature;          

unsigned char myhour, mymin, mysec;
//unsigned char mydate, mymonth, myyear;

/* maximum number of DS18B20 connected to the 1 Wire bus */
#define MAX_DEVICES 2

/* DS18B20 devices ROM code storage area */
unsigned char rom_code[MAX_DEVICES][9];

// Timer 1 overflow interrupt service routine
interrupt [TIM0_OVF] void timer0_ovf_isr(void) {
        PORTD|=0b01111000;                 //   (   "1" -  ..)
        PORTB=digits[digit_out[cur_dig]];       //   
        PORTD&=(cursor[cur_dig]);  //    (   "0" -  ..)
        
        if ((zpt_ON == 1) && (cur_dig == 1)) PORTB.5=1;  //     ( .  )

        cur_dig++; if (cur_dig>=4) cur_dig=0;
}

// -----------------------------------------------------------------------------------------------------------------------------
void init_time (void) {
        unsigned char tmphour, tmpmin, tmpsec1, tmpsec2;
        
        //   (   )
        myhour=12; mymin=0; mysec=0;     // 12-00-00
        //mydate=27; mymonth=2; myyear=7;  // 27.02.2007
        
        rtc_get_time(&tmphour, &tmpmin, &tmpsec1); //     
        delay_ms(3000);
        rtc_get_time(&tmphour, &tmpmin, &tmpsec2); //  3 .    

        if (tmpsec1 == tmpsec2) { //   3 .        
                rtc_set_time(myhour, mymin, mysec);  //  7 (CH)   DS1307     (0 - , 1 - )
                //rtc_set_date(mydate, mymonth, myyear);
                //rtc_init(0, 0, 0); //    DS1307     (   - : rs=0, sqwe=0, out=0) 
        }
}


// -----------------------------------------------------------------------------------------------------------------------------
void time_to_dec(void) {
        unsigned char tmp;
        
        tmp=bin2bcd(myhour);
        digit_out[0] = tmp >> 4;
        digit_out[1] = tmp & 0x0F;
        
        tmp=bin2bcd(mymin);
        digit_out[2] = tmp >> 4;
        digit_out[3] = tmp & 0x0F;
}
 

// ----------------------------    --------------------------------------
//
//   1,5   2  3  2313 (  bit_0  bit_1  D)   
//
void read_key(void) {
        unsigned char i, dr;
               
        if (PIND.0 == 0){
                dr=0;
                for (i=0;i<10;i++){ //   
                        delay_ms(1);
                        if (PIND.0 == 0) dr++;
                } 
                if (dr > 5) {
                        myhour++; if (myhour >= 24) myhour=0;
                        rtc_set_time(myhour, mymin, mysec);
                }
        } 

        if (PIND.1 == 0){
                dr=0;
                for (i=0;i<10;i++){ //   
                        delay_ms(1);
                        if (PIND.1 == 0) dr++;
                } 
                if (dr > 5) {
                        mymin++; if (mymin >= 60) mymin=0;
                        rtc_set_time(myhour, mymin, mysec);
                }
        }
} // ---------------------------------------------------------------------------------------------------------------------------


// -----------------------------------------------------------------------------------------------------------------------------
void hex_to_dec(void) {
        unsigned char celie, drob, tmp;
        unsigned int temp, celie_tmp, drob_tmp;
 
        temp = (unsigned int) temperature;                      
        
        if (temperature>=0) {
                digit_out[0]=PROBEL;       //   ()  
        } 
        else {        
                temp = ( ~temp ) + 0x0001; //       . 
                digit_out[0]=MINUS;        //     (   ..)
             };
        digit_out[3]=GRADUS; zpt_ON=1; 

        celie_tmp = temp >> 4;     //   
        drob_tmp  = temp & 0x000F; //      1/16 
                
        celie = (unsigned char) celie_tmp;  //     
        drob  = (unsigned char) ((drob_tmp * 10) / 16); //      "1/16 "      0,1  
        
        if (celie >= 100) { tmp=bin2bcd(celie-100); digit_out[0] = 1;} else tmp=bin2bcd(celie);
              
        if ((celie >= 100) || ((digit_out[0] == MINUS) && (celie >= 10))) { //    100,0 .   .  -10  1 .
                zpt_ON=0;
                digit_out[1] = tmp >> 4;    // 
                digit_out[2] = tmp & 0x0F;  //  
        }
        
        if ((digit_out[0] == MINUS) && (celie < 10)) { //  . 0   -10  0,1 .
                digit_out[1]=celie; // 
                digit_out[2]=drob;  //  
        }
        
        if ((digit_out[0] == PROBEL) && (celie < 100)) { //  .  100,0    0   0,1 .
                if (tmp >> 4) digit_out[0] = tmp >> 4; //  -       
                digit_out[1] = tmp & 0x0F;             // 
                digit_out[2]=drob;                     //  
        }
}  // ---------------------------------------------------------------------------------------------------------------------------


void main(void) { //================================================= main ========================================================
unsigned char i, devices;
// Declare your local variables here

// Crystal Oscillator division factor: 1
CLKPR=0x80;
CLKPR=0x00;

//     +     
DDRA=0x00;
PORTA=0x00;

//  B   (   0)
DDRB=0xFF;
PORTB=0x00;

//  D ( 6,5,4,3  ,  2,1,0  ,     ( 2),  ( 1,0) )
//   (   "1" -  ..,  6,5,4,3)
DDRD=0x78;   // 01111000
PORTD=0xFB;  // 11111011

// Timer/Counter 0 initialization
// Clock source: System Clock
// Clock value: Timer 0 Stopped
// Mode: Normal top=FFh
// OC0A output: Disconnected
// OC0B output: Disconnected
TCCR0A=0x00;
TCCR0B=0x00;
TCNT0=0x00;
OCR0A=0x00;
OCR0B=0x00;

// Timer/Counter 0 initialization
// Clock source: System Clock
// Clock value: 62,500 kHz
// Mode: Normal top=FFFFh
// OC1A output: Discon.
// OC1B output: Discon.
// Noise Canceler: Off
// Input Capture on Falling Edge
TCCR0A=0x00;
TCCR0B=0x03;

// External Interrupt(s) initialization
// INT0: Off
// INT1: Off
// Interrupt on any change on pins PCINT0-7: Off
GIMSK=0x00;
MCUCR=0x00;

// Timer(s)/Counter(s) Interrupt(s) initialization
TIMSK=0x02;

// Universal Serial Interface initialization
// Mode: Disabled
// Clock source: Register & Counter=no clk.
// USI Counter Overflow Interrupt: Off
USICR=0x00;

// Analog Comparator initialization
// Analog Comparator: Off
// Analog Comparator Input Capture by Timer/Counter 1: Off
ACSR=0x80;

 // 1 Wire Bus initialization
 w1_init();

 devices=w1_search(0xf0,rom_code);
 
 // Global enable interrupts
 #asm("sei")                     

 //  1,5     Fnd '-  '
 //digit_out[0]=13;    // F
 //digit_out[1]=14;    // n
 //digit_out[2]=15;    // d.
 //digit_out[3]=devices; // 'devices'
 //delay_ms(1500);

 init_time(); //  DS1307
   
 // --------------------------------   -----------------------------------
 while (1) {
        for (i=0;i<20;i++){ // 10 .   
                rtc_get_time(&myhour, &mymin, &mysec);
                time_to_dec();
                if (zpt_ON == 1) zpt_ON=0; else zpt_ON=1; //  
                read_key(); // -=-  50  -=-
                delay_ms(500);
        }
        
        if (devices > 1) {  //     
                for (i=0;i<devices;) {
                        temperature=ds18b20_temperature(&rom_code[i++][0]); 
                        if (temperature!=-9999) hex_to_dec();
                        delay_ms(2000);
                }
                //#asm("cli")
                //devices=w1_search(0xf0,rom_code); //   ( )
                //#asm("sei")        
        }
 } // -----------------------------   (end) -----------------------------------

} // =============================================================== end main ==================================================





//
// -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= The End -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
//
                                                                              